
package com.feib.stms.pagination;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @title (#)PaginatedList.java<br>
 * @description describing an externally sorted and paginated list.<br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/10/31 create by Jimmy Liu<br>
 */
public class PaginatedList<E> 
{
	public static final int SORT_DIRECTION_DESC = 1;

	public static final int SORT_DIRECTION_ASC = 2;

	private List<E> paginatedList;

	/** 總計物件 */
	private E totalObject;

	/** 彙總物件 */
	private E totalObject2;

	private int pageNumber = 1;

	private int pageSize = -99;

	private int fullListSize;

	private String sortCriterion;

	private String Message=null;

	private int sortDirection = 2; //2 : ascending, else: descending 

	/**
	 * Returns the current partial list
	 * @return the current partial list
	 */
	public List<E> getPaginatedList()
	{
		return paginatedList;
	}

	/**
	 * set the current partial list
	 */
	public void setPaginatedList(List<E> paginatedList)
	{
		this.paginatedList = paginatedList;
	}

	/**
	 * Returns the page number of the partial list (starts from 1)
	 * @return the page number of the partial list
	 */
	public int getPageNumber()
	{
		return this.pageNumber;
	}

	/**
	 * Returns the page number of the partial list (starts from 1)
	 */
	public void setPageNumber(int pageNumber)
	{
		this.pageNumber = pageNumber;
		if (1 > this.pageNumber)
			this.pageNumber = 1;
	}

	/**
	 * Returns the number of objects per page. Unless this page is the last one the partial list should thus have a size
	 * equal to the result of this method
	 * @return the number of objects per page
	 */
	public int getPageSize()
	{
		if (-99 == this.pageSize){
			Map<String, String> values = new HashMap<String, String> ();//TODO CodeTableUtil.getInstance().populateCodes(CodeTableUtil.CODE_KIND_PAGE_RECORD_SIZE);
			if (null == values || 0 == values.size())
				this.pageSize = 20;
			else
			{
				try {
					this.pageSize = Integer.parseInt(values.keySet().iterator().next());
				}
				catch (Exception e) {
					this.pageSize = 20; 
				}
			}
		}
		return this.pageSize;
	}

	/**
	 * set the number of objects per page. Unless this page is the last one the partial list should thus have a size
	 * equal to the result of this method
	 */
	public void setPageSize(int pageSize)
	{
		this.pageSize = pageSize;
		if (this.pageSize < 1 && -1 != this.pageSize)
		{
			Map<String, String> values = new HashMap<String,String>();//TODO CodeTableUtil.getInstance().populateCodes(CodeTableUtil.CODE_KIND_PAGE_RECORD_SIZE);
			if (null == values || 0 == values.size())
				this.pageSize = 20;
			else
			{
				try {
					this.pageSize = Integer.parseInt(values.keySet().iterator().next());
				}
				catch (Exception e) {
					this.pageSize = 20; 
				}
			} 
		}
	}

	/**
	 * Returns the size of the full list
	 * @return the size of the full list
	 */
	public int getFullListSize()
	{
		return this.fullListSize;
	}

	/**
	 * set the size of the full list
	 */
	public void setFullListSize(int fullListSize)
	{
		this.fullListSize = fullListSize;
	}

	/**
	 * Returns the sort criterion used to externally sort the full list
	 * @return the sort criterion used to externally sort the full list
	 */
	public String getSortCriterion()
	{
		return this.sortCriterion;
	}

	/**
	 * set the sort criterion used to externally sort the full list
	 */
	public void setSortCriterion(String sortCriterion)
	{
		this.sortCriterion = sortCriterion;
	}

	public String getMessage() {
		return this.Message;
	}

	public void setMessage(String message) {
		this.Message = message;
	}
	/**
	 * Returns the sort direction used to externally sort the full list
	 * @return the sort direction used to externally sort the full list, 2 : ascending, else: descending
	 */
	public int getSortDirection()
	{
		return this.sortDirection;
	}

	/**
	 * set the sort direction used to externally sort the full list, 2 : ascending, else: descending
	 */
	public void setSortDirection(int sortDirection)
	{
		this.sortDirection = sortDirection;
	}

	/**
	 * Returns the computed number of pages it would take to show all the elements in the list given the pageSize we are
	 * working with.
	 * @return int computed number of pages
	 */
	public int getTotalPageCount()
	{
		if (-1 == this.pageSize) //顯示全部，所以只有一頁
			return 1;

		int size = this.fullListSize;
		int div = size / this.pageSize;
		int result = (size % this.pageSize == 0) ? div : div + 1;

		return result;
	}

	/**
	 * Returns the index into the master list of the first object that should appear on the current page that the user
	 * is viewing.
	 * @return int index of the first object that should appear on the current page
	 */
	public int getFirstIndexForCurrentPage()
	{
		if (this.pageNumber > getTotalPageCount())
			this.pageNumber =  getTotalPageCount();
		return getFirstIndexForPage(this.pageNumber);
	}

	/**
	 * Returns the index into the master list of the last object that should appear on the current page that the user is
	 * viewing.
	 * @return int
	 */
	public int getLastIndexForCurrentPage()
	{

		return getLastIndexForPage(this.pageNumber);
	}

	/**
	 * Returns the index into the master list of the first object that should appear on the given page.
	 * @param pageNumber page number
	 * @return int index of the first object that should appear on the given page
	 */
	protected int getFirstIndexForPage(int pageNumber)
	{
		/*
        if (-1 == this.pageSize) //顯示全部，所以從第0筆開始顯示
            return 0;

        int retval = (pageNumber - 1) * this.pageSize;
        return retval >= 0 ? retval : 0;
		 */

		/* Oracle是以1為起始值, 非 0為 base*/
		if (-1 == this.pageSize) //顯示全部，所以從第1筆開始顯示
			return 1; 

		int retval = (pageNumber - 1) * this.pageSize + 1; //Oracle是以1為起始值
		return retval >= 1 ? retval : 1;
	}

	/**
	 * Returns the index into the master list of the last object that should appear on the given page.
	 * @param pageNumber page number
	 * @return int index of the last object that should appear on the given page
	 */
	protected int getLastIndexForPage(int pageNumber)
	{
		/*
        int firstIndex = getFirstIndexForPage(pageNumber);
        int pageIndex = this.pageSize - 1;
        int lastIndex = this.fullListSize - 1;

        return Math.min(firstIndex + pageIndex, lastIndex);
		 */
		/* Oracle是以1為起始值, 非 0為 base*/
		int firstIndex = getFirstIndexForPage(pageNumber);
		int pageIndex = this.pageSize-1;
		int lastIndex = this.fullListSize;

		return Math.min(firstIndex + pageIndex, lastIndex);
	}

	/**
	 * 是否最後一頁
	 * 
	 * @return
	 */
	public boolean isLastPage() {
		return getTotalPageCount() <= this.pageNumber;
	}

	public E getTotalObject() {
		return totalObject;
	}

	public void setTotalObject(E totalObject) {
		this.totalObject = totalObject;
	}


	public E getTotalObject2() {
		return totalObject2;
	}

	public void setTotalObject2(E totalObject2) {
		this.totalObject2 = totalObject2;
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("PaginatedList [pageNumber=").append(pageNumber).append(", pageSize=").append(pageSize).append(", fullListSize=").append(fullListSize).append(", sortCriterion=").append(sortCriterion).append(", sortDirection=").append(sortDirection).append("]");
		return builder.toString();
	}

}
